package com.bytz.modules.cms.order.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.bytz.modules.cms.order.constant.OrderPayConstants;
import com.bytz.modules.cms.order.entity.OrderPayDetail;
import com.bytz.modules.cms.order.mapper.OrderPayDetailMapper;
import com.bytz.modules.cms.order.model.PayNotifyResult;
import com.bytz.modules.cms.order.service.IOrderPayDetailService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;

/**
 * <p>
 * 莱宝CMS—订单管理-订单交易支付明细表 服务实现类
 * </p>
 *
 * @author KyleWang
 * @since 2022-10-10
 */
@Service
public class OrderPayDetailServiceImpl extends ServiceImpl<OrderPayDetailMapper, OrderPayDetail> implements IOrderPayDetailService {

    @Override
    public void saveOrderPayDetails(String orderId, String payId, List<OrderPayDetail> payDetails) {
        for (OrderPayDetail payDetail : payDetails) {
            payDetail.setOrderId(orderId);
            payDetail.setOrderPayId(payId);
        }

        saveBatch(payDetails);
    }

    @Override
    public List<OrderPayDetail> getByOrderId(String orderId) {
        return lambdaQuery().eq(OrderPayDetail::getOrderId, orderId).list();
    }

    @Override
    public List<OrderPayDetail> getByPayId(String payId) {
        return lambdaQuery().eq(OrderPayDetail::getOrderPayId, payId).list();
    }

    @Override
    public List<OrderPayDetail> getOfflinePayByPayId(String orderPayId) {
        return lambdaQuery()
                .eq(OrderPayDetail::getOrderPayId, orderPayId)
                .eq(OrderPayDetail::getPayWay, OrderPayConstants.PayWay.OFFLINE)
                .list();
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void submitOfflinePay(String orderPayId) {
        updateOfflinePayStatus(orderPayId, OrderPayConstants.PayStatus.DONE);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void rollbackOfflinePay(String orderPayId) {
        updateOfflinePayStatus(orderPayId, OrderPayConstants.PayStatus.FAILED);
    }

    /**
     * 更新线下支付状态
     */
    private void updateOfflinePayStatus(String orderPayId, String status) {
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMdd");
        lambdaUpdate()
                .set(OrderPayDetail::getStatus, status)
                .set(OrderPayDetail::getCompleteDate, LocalDate.now().format(formatter))
                .set(OrderPayDetail::getCompleteDateTime, LocalDateTime.now())
                .eq(OrderPayDetail::getOrderPayId, orderPayId)
                .eq(OrderPayDetail::getPayWay, OrderPayConstants.PayWay.OFFLINE)
                .update();
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void updatePayResponse(PayNotifyResult payNotifyResult) {
        lambdaUpdate()
                .set(OrderPayDetail::getPayResponse, payNotifyResult.getPayResponse().toPlainString())
                .set(OrderPayDetail::getErrorMessage, "")
                .eq(OrderPayDetail::getId, payNotifyResult.getPayDetailId())
                .update();
    }

    @Override
    public void submitOnlinePay(OrderPayDetail orderPayDetail, PayNotifyResult payNotifyResult) {
        updateOnlinePayResult(payNotifyResult, OrderPayConstants.PayStatus.DONE);
    }

    @Override
    public void rollbackOnlinePay(OrderPayDetail orderPayDetail, PayNotifyResult payNotifyResult) {
        updateOnlinePayResult(payNotifyResult, OrderPayConstants.PayStatus.FAILED);
    }

    @Override
    public void logErrorMessage(String payDetailId, String message) {
        lambdaUpdate()
                .set(OrderPayDetail::getErrorMessage, message)
                .eq(OrderPayDetail::getId, payDetailId)
                .update();
    }

    /**
     *  更新在线支付结果
     */
    private void updateOnlinePayResult(PayNotifyResult payNotifyResult, String status) {
        lambdaUpdate()
                .set(OrderPayDetail::getPayResponse, payNotifyResult.getPayResponse().toPlainString())
                .set(OrderPayDetail::getErrorMessage, "")
                .set(OrderPayDetail::getStatus, status)
                .set(OrderPayDetail::getPaySource, payNotifyResult.getPaySource())
                .set(OrderPayDetail::getTransactionNumber, payNotifyResult.getTransactionNumber())
                .set(OrderPayDetail::getCompleteDate, payNotifyResult.getCompleteDate())
                .set(OrderPayDetail::getCompleteDateTime, payNotifyResult.getCompleteDateTime())
                .eq(OrderPayDetail::getId, payNotifyResult.getPayDetailId())
                .update();
    }
}
